package com.example.demo.service.imply;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.constant.PageBankCategoryConstant;
import com.example.demo.exception.MyUncheckedException;
import com.example.demo.mapper.*;
import com.example.demo.pojo.TreeQuestionLabel;
import com.example.demo.pojo.tree.TreeSubjectFile;
import com.example.demo.pojo.dto.BankGroupDTO;
import com.example.demo.pojo.dto.CategoryBankDTO;
import com.example.demo.pojo.dto.ExamPaperDTO;
import com.example.demo.pojo.dto.QuestionConnectDTO;
import com.example.demo.pojo.entity.*;
import com.example.demo.pojo.vo.ExamCategoryVO;
import com.example.demo.pojo.vo.ExamPaperVO;
import com.example.demo.pojo.vo.ExamQuestionVO;
import com.example.demo.pojo.vo.PageBankShowVO;
import com.example.demo.service.IExamPaperService;
import io.swagger.models.auth.In;
import lombok.RequiredArgsConstructor;
import org.aspectj.weaver.patterns.TypePatternQuestions;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author fjh
 */
@Service
@RequiredArgsConstructor
public class IExamPaperServiceImply extends ServiceImpl<ExamPaperMapper, ExamPaper> implements IExamPaperService {
    private final ExamPaperMapper examPaperMapper;
    private final ExamQuestionMapper examQuestionMapper;
    private final ExamCategoryMapper examCategoryMapper;
    private final QuestionBankMapper questionBankMapper;
    private final QuestionClassificationMapper questionClassificationMapper;
    private final QuestionLabelMapper questionLabelMapper;
    private final QuestionFileMapper questionFileMapper;
    private final SubjectFileMapper subjectFileMapper;
    private final SubjectMapper subjectMapper;
    private final QuestionCategoryMapper questionCategoryMapper;
    private final ExamPaperFileMapper examPaperFileMapper;
    //service注入
    private final ISubjectFileServiceImply subjectFileService;
    private final ILabelServiceImply questionLabelService;
    private final ExamFileMapper examFileMapper;

    /**
     * 通过文件夹建立试卷
     * @author: fjh
     * @param:
     * @return:
    **/
    @Override
    public List<PageBankShowVO> initByFile(Integer subjectId,Integer categoryId) {
        System.out.println("当前条件进入到只文件处理");
        QueryWrapper<Subject> querySubjectWrapper=new QueryWrapper<>();
        Subject subject=subjectMapper.selectById(subjectId);
        int fileId=subject.getFileId();
        SubjectFile subjectFile=subjectFileMapper.selectById(fileId);
        QueryWrapper<SubjectFile> queryFileIdWrapper = new QueryWrapper<>();
        queryFileIdWrapper.likeRight("node_id",fileId+"-");
        List<Integer> needIdList = subjectFileMapper.selectList(queryFileIdWrapper).stream().map(SubjectFile::getId).collect(Collectors.toList());
        //处理题目表
        return completePageBankShowListByFile(subjectFile,needIdList);
    }
    /**
     * 打包函数--将树的信息打包为pageBankShow返回--关于文件
     * @author: fjh
     * @param:
     * @return:
    **/List<PageBankShowVO> completePageBankShowListByFile(SubjectFile subjectFile,List<Integer>needIdList) {
        TreeSubjectFile treeSubjectFile=subjectFileService.initTreeSubjectFile(subjectFile,needIdList);
        PageBankShowVO pageBankShowVO=new PageBankShowVO();
        pageBankShowVO.initSubjectFile(subjectFile);
        List<TreeSubjectFile>addList=new ArrayList<>();
        addList.add(treeSubjectFile);
        return solvePageBankShowVoByFile(addList);
    }

    /**
     *递归的处理打包pageBankShow
     * @author: fjh
    **/
    private List<PageBankShowVO> solvePageBankShowVoByFile(List<TreeSubjectFile> children) {
        if(children==null){
            return null;
        }
        List<PageBankShowVO>result=new ArrayList<>();
        for(int i=0;i<children.size();i++){
            PageBankShowVO pageBankShowVO=new PageBankShowVO();
            TreeSubjectFile treeSubjectFile=children.get(i);
            SubjectFile subjectFile=treeSubjectFile.getSubjectFile();
            //获得当前节点的subjectFile--开始处理查找题目的数量
            QueryWrapper<QuestionFile>queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("file_id",subjectFile.getId());
            List<QuestionFile>questionFileList=questionFileMapper.selectList(queryWrapper);
            if(questionFileList!=null){
                pageBankShowVO.setRealNumber(questionFileList.size());
            }else{
                pageBankShowVO.setRealNumber(0);
            }
            List<PageBankShowVO>solveResult=solvePageBankShowVoByFile(treeSubjectFile.getChildren());
            pageBankShowVO.setChildrenLabelList(solveResult);
            result.add(pageBankShowVO);
        }

        return result;
    }
    /**
     * 通过题型选取建立卷子
     * @author: fjh
    **/
    @Override
    public List<PageBankShowVO> initByLabel(Integer subjectId,Integer categoryId) {
        System.out.println("当前条件进入到只题型处理");
        Subject subject=subjectMapper.selectById(subjectId);
        int labelId=subject.getLabelId();
        QuestionLabel questionLabel=questionLabelMapper.selectById(labelId);
        QueryWrapper<QuestionLabel> queryLabelIdWrapper = new QueryWrapper<>();
        queryLabelIdWrapper.likeRight("node_id",labelId+"-");
        List<Integer> needIdList = questionLabelMapper.selectList(queryLabelIdWrapper).stream().map(QuestionLabel::getId).collect(Collectors.toList());
        //处理题目表
        return completePageBankShowListByLabel(questionLabel,categoryId,needIdList);
    }
    //复制函数--遍历所有的label然后获取其下的虚题目与实题目
    void getAllLabelClassificationNumber(){
        int rootId=1;
    }
    /**
     * 打包函数--将树的信息打包为pageBankShow返回--关于题型建立试卷
     * @author: fjh
     * @param:
     * @return:
    **/
    private List<PageBankShowVO> completePageBankShowListByLabel(QuestionLabel questionLabel,int categoryId, List<Integer> needIdList) {
        TreeQuestionLabel treeQuestionLabel=questionLabelService.initTreeQuestionLabel(questionLabel,needIdList);
        PageBankShowVO pageBankShowVO=new PageBankShowVO();
        pageBankShowVO.initQuestionLabel(questionLabel);
        List<TreeQuestionLabel>addList=new ArrayList<>();
        addList.add(treeQuestionLabel);
        return solvePageBankShowVoByLabel(addList,categoryId);
    }

    private List<PageBankShowVO> solvePageBankShowVoByLabel(List<TreeQuestionLabel> children,int categoryId) {
        if(children==null){
            return null;
        }
        List<PageBankShowVO>result=new ArrayList<>();
        for(int i=0;i<children.size();i++){
            PageBankShowVO pageBankShowVO=new PageBankShowVO();
            TreeQuestionLabel treeQuestionLabel=children.get(i);
            QuestionLabel questionLabel=treeQuestionLabel.getQuestionLabel();
            //开始处理实虚题目
            int labelId=questionLabel.getId();
            String nodeId=questionLabel.getNodeId();
//            QueryWrapper<QuestionClassification>queryWrapperReal=new QueryWrapper<>();
//            QueryWrapper<QuestionClassification>queryWrapperImage=new QueryWrapper<>();
//            queryWrapperReal.eq("question_label_id",labelId);
//            List<Integer>realIList=questionClassificationMapper.selectList(queryWrapperReal).stream().map(QuestionClassification::getId).collect(Collectors.toList());
            List<QuestionConnectDTO>realList=questionClassificationMapper.getRealNumber(categoryId,labelId);
//            queryWrapperImage.likeRight("node_id",nodeId);
//            List<Integer>imageList=questionClassificationMapper.selectList(queryWrapperImage).stream().map(QuestionClassification::getId).collect(Collectors.toList());
            List<QuestionConnectDTO>imageList=questionClassificationMapper.getImageNumber(categoryId,nodeId);
            pageBankShowVO.setRealNumber(realList.size());
            pageBankShowVO.setImageNumber(imageList.size()+realList.size());
//            pageBankShowVO.setLabelName(questionLabel.getName());
            pageBankShowVO.initQuestionLabel(questionLabel);
            pageBankShowVO.setShowCategory(PageBankCategoryConstant.label_only);
            List<PageBankShowVO>solveResult=solvePageBankShowVoByLabel(treeQuestionLabel.getChildren(),categoryId);
            pageBankShowVO.setChildrenLabelList(solveResult);
            result.add(pageBankShowVO);
        }
        return result;
    }
    /**
     * 通过题型和知识点建立卷子
     * @author: fjh
     * @param:
     * @return:
    **/
    @Override
    public List<PageBankShowVO> initByFl(Integer subjectId,Integer categoryId) {
//        System.out.println("进入到文件与题目选择");
        Subject subject=subjectMapper.selectById(subjectId);
        int labelId=subject.getLabelId();
        int fileId=subject.getFileId();
        SubjectFile subjectFile=subjectFileMapper.selectById(fileId);
        return null;
    }
    /**
     * 删除卷子，所有文件下的卷子都删除
     * @author: fjh
    **/
    @Override
    public boolean delete(int paperId) {
        ExamPaper examPaper=examPaperMapper.selectById(paperId);
        examPaperMapper.deleteById(examPaper);
        QueryWrapper<ExamPaperFile>queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("exam_paper_id",paperId);
        List<Integer>deleteIdList=examPaperFileMapper.selectList(queryWrapper).stream().map(ExamPaperFile::getId).collect(Collectors.toList());
        examPaperFileMapper.deleteBatchIds(deleteIdList);
        return true;
    }
    /**
     * 复制试卷，需要将三个表的信息都实现复制
     * @author: fjh
     * @param: examPaperId：操作的卷子
     * @param: goalExamFileId: 目标文件的id
     * @return: 复制后新获得的卷子信息
    **/
    @Override
    public ExamPaper copyExamPaper(int examPaperId, int goalExamFileId) {
        //建立新的卷子信息
        ExamPaper oldExamPaper=examPaperMapper.selectById(examPaperId);
        ExamPaper newExamPaper=new ExamPaper();
        newExamPaper.initExamPaper(oldExamPaper);
        examPaperMapper.insert(newExamPaper);
        //绑定到卷子文件表中
        int newExamPaperId=newExamPaper.getId();
        ExamFile examFile=examFileMapper.selectById(goalExamFileId);
        ExamPaperFile examPaperFile=new ExamPaperFile();
        examPaperFile.setExamFileId(goalExamFileId);
        examPaperFile.setExamPaperId(newExamPaperId);
        examPaperFile.setNodeId(examFile.getNodeId());
        examPaperFileMapper.insert(examPaperFile);
        //将卷子下的题型选择
        QueryWrapper<ExamCategory>examCategoryQueryWrapper=new QueryWrapper<>();
        examCategoryQueryWrapper.eq("exam_id",examPaperId);
        List<ExamCategory>examCategoryList=examCategoryMapper.selectList(examCategoryQueryWrapper);
        for(ExamCategory examCategoryFor:examCategoryList){
            //将复制到的卷子题型信息插入
            ExamCategory examCategory=new ExamCategory();
            examCategory.initExamCategory(examCategoryFor);
//            System.out.println(newExamPaperId);
            examCategory.setExamId(newExamPaperId);
            examCategoryMapper.insert(examCategory);
            //获取题型下的所有题目关联再建立新的联系
            int oldExamCategoryId=examCategoryFor.getId();
            int newExamCategoryId=examCategory.getId();
            QueryWrapper<ExamQuestion>examQuestionQueryWrapper=new QueryWrapper<>();
            examQuestionQueryWrapper.eq("exam_category_id",oldExamCategoryId);
            List<ExamQuestion>examQuestionList=examQuestionMapper.selectList(examQuestionQueryWrapper);
            for(ExamQuestion examQuestionFor:examQuestionList){
                ExamQuestion newExamQuestion=new ExamQuestion();
                newExamQuestion.initExamQuestion(examQuestionFor);
                newExamQuestion.setExamCategoryId(newExamCategoryId);
                examQuestionMapper.insert(newExamQuestion);
            }
        }

        return null;
    }
    /**
     * 转移卷子，只需要将文件的id改变
     * @author: fjh
    **/
    @Override
    public ExamPaperFile shiftExamPaper(int examPaperId, int goalExamFileId) {
        ExamPaper examPaper=examPaperMapper.selectById(examPaperId);
//        ExamPaperFile examPaperFile=
        QueryWrapper<ExamPaperFile>examPaperFileQueryWrapper=new QueryWrapper<>();
        examPaperFileQueryWrapper.eq("exam_paper_id",examPaperId);
        List<ExamPaperFile>examPaperFileList=examPaperFileMapper.selectList(examPaperFileQueryWrapper);
        if(!examPaperFileList.isEmpty()){
            ExamPaperFile examPaperFile=examPaperFileList.get(0);
            UpdateWrapper<ExamPaperFile>examPaperFileUpdateWrapper=new UpdateWrapper<>();
            examPaperFileUpdateWrapper.eq("id",examPaperFile.getId());
            examPaperFile.setExamFileId(goalExamFileId);
            examPaperFileMapper.update(examPaperFile,examPaperFileUpdateWrapper);
            return examPaperFile;
        }
        return null;
    }
    /**
     * 根据试卷id查找完整试卷信息，包含题目，题型，基本描述等
     * @author: fjh
    **/
    @Override
    public ExamPaperVO searchById(int examPaperId) throws MyUncheckedException {
        ExamPaper examPaper=examPaperMapper.selectById(examPaperId);
        if(examPaper==null){
            return null;
        }
        //得到试卷的基本信息
        ExamPaperVO examPaperVO=new ExamPaperVO();
        examPaperVO.initExamPaper(examPaper);
        //得到试卷的题型关联信息
        List<ExamCategoryVO>examCategoryVOList=new ArrayList<>();
        QueryWrapper<ExamCategory>examCategoryQueryWrapper=new QueryWrapper<>();
        examCategoryQueryWrapper.eq("exam_id",examPaperId);
        List<ExamCategory>examCategoryList;
        examCategoryList=examCategoryMapper.selectList(examCategoryQueryWrapper);
        if(examCategoryList.isEmpty()){
            throw new MyUncheckedException("卷子下题型查找失败");
        }
        int indexId=1;
        for(ExamCategory examCategoryFor:examCategoryList){
            //添加到列表中
            ExamCategoryVO examCategoryVO=new ExamCategoryVO();
            examCategoryVO.initExamCategory(examCategoryFor);
            //获取题型名字
            int categoryId=examCategoryFor.getCategoryId();
            QuestionCategory questionCategory=questionCategoryMapper.selectById(categoryId);
            examCategoryVO.setCategoryName(questionCategory.getName());
            //处理当前题型下的相关题目
            List<ExamQuestionVO>examQuestionVOList=new ArrayList<>();
            int examCategoryId=examCategoryFor.getId();
            QueryWrapper<ExamQuestion>examQuestionQueryWrapper=new QueryWrapper<>();
            examQuestionQueryWrapper.eq("exam_category_id",examCategoryId);
            List<ExamQuestion> examQuestionList=examQuestionMapper.selectList(examQuestionQueryWrapper);
            for(ExamQuestion examQuestionFor:examQuestionList){
                ExamQuestionVO examQuestionVO=new ExamQuestionVO();
                int questionId=examQuestionFor.getQuestionId();
                QuestionBank questionBank=questionBankMapper.selectById(questionId);
                if(questionBank==null){
                    continue;
                }
                examQuestionVO.initQuestion(questionBank);
                examQuestionVO.setIndexId(indexId);
                indexId=indexId+1;
                examQuestionVOList.add(examQuestionVO);
            }
            examCategoryVO.setExamQuestionList(examQuestionVOList);
            examCategoryVOList.add(examCategoryVO);
        }
        examPaperVO.setExamPaperCategoryList(examCategoryVOList);
        return examPaperVO;
    }

    /**
     * 创建新卷子
     * @author: fjh
     * @param: examPaperDTO：包含卷子的相关信息
     * @return: ExamPaper：将建立的卷子返回
    **/
    @Override
    public ExamPaper createPaper(ExamPaperDTO examPaperDTO) {
        int paperNumber=examPaperDTO.getPaperNumber();
        List<List<Integer>>checkList=new ArrayList<>();
        for(int i=0;i<paperNumber;i++){
            ExamPaper examPaper=new ExamPaper();
            String paperName=examPaperDTO.getPaperName();
            if(i!=0){
                paperName=paperName+"("+i+")";
            }
            //构建卷子的实体类
            examPaper.setExamPaperName(paperName);
            examPaper.setQuestionCount(examPaperDTO.getPaperNumber());
            examPaper.setAverageDifficulty(examPaperDTO.getAverageDifficulty());
            examPaper.setDescription(examPaperDTO.getDescription());
            examPaper.setTotalScore(examPaperDTO.getPaperTotalScore());
            examPaper.setCategory(examPaperDTO.getCategory());
            examPaper.setCreateUser(examPaperDTO.getCreateUser());
            examPaperMapper.insert(examPaper);
            int examPaperId=examPaper.getId();
            //将生成的卷子与根文件关联
            int subjectId=examPaperDTO.getSubject();
            Subject subject=subjectMapper.selectById(subjectId);
            int examFileId=subject.getExamFileId();
            ExamPaperFile examPaperFile=new ExamPaperFile();
            examPaperFile.setExamFileId(examFileId);
            examPaperFile.setExamPaperId(examPaperId);
            examPaperFileMapper.insert(examPaperFile);
            //处理卷子下的题型
            List<CategoryBankDTO>categoryBankDTOList=examPaperDTO.getCategoryBankDTOList();
            int category= examPaper.getCategory();
            solveExamCategory(categoryBankDTOList,examPaperId,category);
        }
        return null;
    }
    /**
     * 辅助函数--处理卷子下不同题型的选题
     * @author: fjh
     * @param:
     * @return:
    **/
    public void solveExamCategory(List<CategoryBankDTO>categoryBankDTOList,int examId,int category){
        for(CategoryBankDTO categoryBankDTO:categoryBankDTOList){
            ExamCategory examCategory=new ExamCategory();
            examCategory.setCategoryId(categoryBankDTO.getBankCategory());
            examCategory.setExamId(examId);
            examCategory.setDescription(categoryBankDTO.getBankDescription());
            examCategory.setQuestionScore(categoryBankDTO.getBankScore());
            examCategory.setQuestionNumber(categoryBankDTO.getBankNumber());
            examCategoryMapper.insert(examCategory);
            //绑定题型
            List<BankGroupDTO>bankGroupDTOList=categoryBankDTO.getBankGroupDTOList();
            int examCategoryId=examCategory.getId();
            int categoryId=categoryBankDTO.getBankCategory();
            solveExamQuestion(bankGroupDTOList,examCategoryId,categoryId,category);
        }
    }
    /**
     * 辅助函数--处理题型选题下的题目绑定
     * @author: fjh
     * @param:
     * @return:
    **/
    public void solveExamQuestion(List<BankGroupDTO>bankGroupDTOList,int examCategoryId,int categoryId,int selectCategory){
        for(BankGroupDTO bankGroupDTO:bankGroupDTOList){
            if(selectCategory==1){
                //category=1表示只进行题型
                int labelId=bankGroupDTO.getLabelId();
                QuestionLabel questionLabel=questionLabelMapper.selectById(labelId);
                int number=bankGroupDTO.getNumber();
                List<Integer>questionIdList=questionClassificationMapper.getBankList(categoryId,labelId);
//                System.out.println("当前处理的是"+questionLabel.getName());
//                System.out.println("一共具有"+questionIdList.size());
//                System.out.println("准备选取"+number+"条数据");
                Collections.shuffle(questionIdList);
                List<Integer> selectedId = questionIdList.subList(0, number);
                for(int i=0;i<selectedId.size();i++){
                    ExamQuestion examQuestion=new ExamQuestion();
                    examQuestion.setExamCategoryId(examCategoryId);
                    examQuestion.setQuestionId(selectedId.get(i));
                    examQuestionMapper.insert(examQuestion);
                }
            }
        }
    }
}
